 Homeworld File Format
Documentation .Lif File Format By B1FF (lmoloney@relic.com)
©
2000 Relic Entertainment, Inc.
Preamble The .LiF extension (note the wacky
capitalization) is short for "Layered image Format". This format is
the image storage method for Homeworld. It is mostly used for
textures but also finds use for front end graphics, cursor bitmaps
and tutorial button graphics. It actually has two general formats
which share a common header. Also released will be the tool we use
to create .LiF files. Initially, we supported many different layers
for image blending but in an effort to improve loading time and
reduce texture usage, we tried crunching a 5-dimensional color space
into 8 bits using a lossy quantization algorithm. I'm not going to
explain the alogorithm because I mostly forget how it worked - and I
created it! Anyhow, here's the file format.
.LiF File
Header Here is the header to the file:
//format for the
.LiF files typedef struct { char ident[8]; //compared to
"Willy 7" sdword version; //version number sdword flags; //to
plug straight into texreg flags sdword width, height;
//dimensions of image crc32 paletteCRC; //a CRC of palettes for
fast comparison crc32 imageCRC; //crc of the unquantized
image ubyte *data; //actual image color *palette; //palette
for this image ubyte *teamEffect0, *teamEffect1; //palettes of
team color effect // sdword nSizes; //number of sizes
encoded // udword image[LLC_NumberImages]; //offset-pointers to
the individual images (from end of this header) } lifheader;
Ident - self-explanatory. Version - 0x104 as of release.
Will stay here. Flags - bitmasks of the following: #define
TRF_Alpha 0x00000008 //alpha channel image #define TRF_TeamColor0
0x00000010 //team color flags #define TRF_TeamColor1
0x00000020 All other bitmasks ignored. TeamColor0 is the base
color, TeamColor1 is the stripe color. Width, height - size of
image. PaletteCRC - 32-bit CRC of palette. All palette CRC's for
a ship should be the same and unique compared to all other ships.
Important for shared palettes! ImageCRC - 32-bit CRC of image.
Ignore this. Only used for creation. Data - offset to image
data Palette - offset to palette (if a paletted image, 0
otherwise) TeamEffect0 - Offset to 'base color influence image or
palette'. TeamEffect1 - Offset to 'stripe color influence image
or palette'.
If the image has an alpha channel, the image is
loaded as an RGBA image. The palette is ignored and the
TeamEffect0/1 buffers are blended with the main image using this
algorithm:
/*----------------------------------------------------------------------------- Name
: trBufferColorRGB Description : Colorize an image (or palette)
based upon team effect buffers Inputs : dest - where to put the
colorized image source - where to read the uncolorized
version teamEffect0,1 - team color effect buffers teamColor0,1
- team colors to colorize to size - size fo buffer, in
pixels flags - texreg flags telling us how to colorize the
image effectScalar0, effectScalar1 - scalar of the team effect
values to be read. Outputs : Return :
void ----------------------------------------------------------------------------*/ void
trBufferColorRGB(color *dest, color *source, ubyte *teamEffect0,
ubyte *teamEffect1, color teamColor0, color teamColor1, sdword
size, udword flags, real32 effectScalar0, real32
effectScalar1) { real32 teamRed0 =
colUbyteToReal(colRed(teamColor0)); real32 teamRed1 =
colUbyteToReal(colRed(teamColor1)); real32 teamGreen0 =
colUbyteToReal(colGreen(teamColor0)); real32 teamGreen1 =
colUbyteToReal(colGreen(teamColor1)); real32 teamBlue0 =
colUbyteToReal(colBlue(teamColor0)); real32 teamBlue1 =
colUbyteToReal(colBlue(teamColor1)); real32 redSource,
greenSource, blueSource, redDest, greenDest, blueDest, effectReal0,
effectReal1;
while (size > 0) { //read the info from
buffers into floating point redSource =
colUbyteToReal(colRed(*source)); greenSource =
colUbyteToReal(colGreen(*source)); blueSource =
colUbyteToReal(colBlue(*source)); if (bitTest(flags,
TRF_TeamColor0)) { effectReal0 = min(1.0f,
colUbyteToReal(*teamEffect0) *
effectScalar0); } else { effectReal0 = 0.0f; } if
(bitTest(flags, TRF_TeamColor1)) { effectReal1 = min(1.0f,
colUbyteToReal(*teamEffect1) *
effectScalar1); } else { effectReal1 =
0.0f; } //blend redDest = redSource * (1.0f - effectReal0)
+ teamRed0 * effectReal0; redDest = redDest * (1.0f -
effectReal1) + teamRed1 * effectReal1; greenDest = greenSource *
(1.0f - effectReal0) + teamGreen0 * effectReal0; greenDest =
greenDest * (1.0f - effectReal1) + teamGreen1 *
effectReal1; blueDest = blueSource * (1.0f - effectReal0) +
teamBlue0 * effectReal0; blueDest = blueDest * (1.0f -
effectReal1) + teamBlue1 * effectReal1; //write back *dest =
colRGBA(colRealToUbyte(redDest), colRealToUbyte(greenDest),
colRealToUbyte(blueDest), colAlpha(*source)); //update
pointers size--; dest++; source++; teamEffect0++; teamEffect1++; } }
Note that a paletted image has its palette blended with its
team color palettes using the same algorithm.
So there you
have the file format. This file format is actually of little use,
however, unless you want to extract the art from Homeworld. To
create .LiF files, Relic will release a command-line tool we used to
create these files.
.LiF Listing file
(textures.ll) Textures.ll is a database of textures used to speed
up the measurement of textures for texture packing. While you don't
have to add your textures to this database, you might find it useful
to look at. The same tool we use to make the .LiF files maintains
this database.
Creating .LiF files. .Lif files are
created from Adobe Photoshop files (.PSD). These files support the
layering and blending we so wanted. The ordering of blending is the
same in our .LiF exporter as in Photoshop. The names of layers
determines their usage. Following is the recognized names for layers
and their common blending mode. -"COL 1", "COL1" - base color
layer. Usually overlay mode. -"COL 2", "COL2" - can you
guess? -"TEX" - The actual texture layer. Usually base layer,
normal blending. -"LAB", "PB", "PW", "DIRT" - detail
layers -"ALPHA" alpha channel, if there is one. Use multiply and
stick it on top of everything.
When you have a list of
textures you want to "quatnize" into .LiF files, use the following
batch file, onebunchalifs.bat, or some derivative thereof:
@pushd
@if "%1"==%1 goto
about
@cd\homeworld
@if exist datasrc\%1\dependtex.mif
del datasrc\%1\dependtex.mif > NUL @echo # >
datasrc\%1\dependtex.mif @for %filename in (datasrc\%1\*.psd)
echo TEXTURES += %@name[%filename].lif >>
datasrc\%1\dependtex.mif @liflist q data\textures.ll
datasrc\%1\dependtex.mif @del datasrc\%1\dependtex.mif >
NUL goto end
:about @echo USAGE: OneBunghaLifs
:end
@popd
For example, to make the highest
LOD of the R1 Support Frigate, type:
OneBunchaLifs
R1\AdvanceSupportFrigate\Rl0\LOD0
| |
 |